package com.bjy.qa.service.functionaltest.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bjy.qa.dao.functionaltest.*;
import com.bjy.qa.entity.Response;
import com.bjy.qa.entity.functionaltest.*;
import com.bjy.qa.enumtype.CatalogType;
import com.bjy.qa.enumtype.EditStatus;
import com.bjy.qa.exception.MyException;
import com.bjy.qa.service.functionaltest.IReviewExecuteService;
import com.bjy.qa.service.functionaltest.IReviewsResultService;
import com.bjy.qa.service.functionaltest.ITestCaseService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@Service
public class ReviewExecuteService extends ServiceImpl<ReviewsDao, Reviews> implements IReviewExecuteService {

    @Resource
    private CatalogDao catalogDao;

    @Resource
    ITestCaseService iTestCaseService;

    @Resource
    TestCaseDao testCaseDao;

    @Resource
    IReviewsResultService iReviewsResultService;

    @Resource
    ReviewsResultDao reviewsResultDao;

    @Resource
    ReviewsDao reviewsDao;

    @Resource
    ReviewsRemarkDao reviewsRemarkDao;

    @Override
    public List<FullTree> listTree(CatalogType type, CatalogType caseType, Long projectId, Long reviewsId, Long parentId){
        if (reviewsId == null || reviewsId == 0) {
            throw new MyException("查询 测试套件 tree 失败：reviewsId 不能为空");
        }

        if (type == CatalogType.TEST_CASE || type == CatalogType.INTERFACE_TEST_CASE) {
            return recursiveQueryTree("ft_test_case", type,type, caseType, projectId, reviewsId, parentId);
        } else {
            throw new MyException("查询 tree 上某个type所有数据列表失败：type 未知，type: " + type + ", type.value: " + type.getValue());
        }
    }

    private List<FullTree> recursiveQueryTree(String elementTableName, CatalogType catalogType, CatalogType elementType, CatalogType caseType, Long projectId, Long reviewsId, Long parentId) {
        List<FullTree> fullTrees = null;
        if ("ft_test_case".equals(elementTableName)) {
            fullTrees = catalogDao.listReviewsCheckedTestCaseTree(catalogType, elementType, caseType, projectId, reviewsId, parentId);
        } else {
            throw new MyException("查询 tree 上某个type所有数据列表失败：elementTableName 未知，elementTableName: " + elementTableName);
        }

        for (FullTree fullTree : fullTrees) {
            if (fullTree.getIsCatalog()) {
                fullTree.setChildren(recursiveQueryTree(elementTableName, catalogType, elementType, caseType, projectId, reviewsId, fullTree.getId()));
            }
        }

        Iterator<FullTree> iterator = fullTrees.iterator();
        while (iterator.hasNext()) {
            FullTree fullTree = iterator.next();
            if(fullTree.getIsCatalog() && (fullTree.getChildren() == null || fullTree.getChildren().size() == 0)) {
                iterator.remove();
            }
        }

        return fullTrees;
    }

    @Override
    public Response<String> updateCaseStatus(ReviewsExecuteDataDTO reviewsExecuteDataDTO, String runUser) {
        Reviews reviews = reviewsDao.selectById(reviewsExecuteDataDTO.getReviewsId());
        TestCase testCase = testCaseDao.findById(reviewsExecuteDataDTO.getTestCaseId());
        if (reviews != null && testCase != null) {
            if (reviews.getStatus().getValue() == EditStatus.FINISH.getValue()) {
                throw new MyException("该评审已经结束，不能再更新评审数据！");
            }

            // 修改测试用例编写状态
            testCase.setEditStatus(reviewsExecuteDataDTO.getCaseStatus());
            testCaseDao.updateById(testCase);

            // 删除旧的评审结果
            QueryWrapper<ReviewsResult> queryReviewsResultWrapper = new QueryWrapper<>();
            queryReviewsResultWrapper.eq("project_id", reviews.getProjectId());
            queryReviewsResultWrapper.eq("reviews_id", reviewsExecuteDataDTO.getReviewsId());
            queryReviewsResultWrapper.eq("test_case_id", reviewsExecuteDataDTO.getTestCaseId());
            reviewsResultDao.delete(queryReviewsResultWrapper);

            // 新增评审结果
            ReviewsResult reviewsResult = new ReviewsResult();
            reviewsResult.setProjectId(reviews.getProjectId());
            reviewsResult.setReviewsId(reviewsExecuteDataDTO.getReviewsId());
            reviewsResult.setTestCaseId(reviewsExecuteDataDTO.getTestCaseId());
            reviewsResult.setStatus(reviewsExecuteDataDTO.getCaseStatus());
            reviewsResultDao.insert(reviewsResult);

            // 修改评审计划表中的 通过率 和 通过用例数
            QueryWrapper<ReviewsResult> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("project_id", reviews.getProjectId());
            queryWrapper.eq("reviews_id", reviewsExecuteDataDTO.getReviewsId());
            queryWrapper.eq("status", EditStatus.FINISH.getValue());
            reviews.setPassTestCases(reviewsResultDao.selectCount(queryWrapper).intValue());
            reviews.setPassRate(((Double) ((double) reviews.getPassTestCases() / (double) reviews.getTotalTestCase() * 100)).intValue());

            // 修改评审计划表中的 已评人数
            QueryWrapper<ReviewsRemark> queryReviewsRemarkWrapper = new QueryWrapper<>();
            queryReviewsRemarkWrapper.eq("project_id", reviews.getProjectId());
            queryReviewsRemarkWrapper.eq("reviews_id", reviewsExecuteDataDTO.getReviewsId());
            queryReviewsRemarkWrapper.select("DISTINCT reviewer_user_id");
            reviews.setReviewers(reviewsRemarkDao.selectCount(queryReviewsRemarkWrapper).intValue());

            reviewsDao.updateById(reviews);
        }

        return Response.success("更新测试用例编写状态执行成功！");
    }

    @Override
    public Response<String> batchUpdateCaseStatus(BatchReviewsExecuteDataDTO batchReviewsExecuteDataDTO, String runUser) {
        Reviews reviews = reviewsDao.selectById(batchReviewsExecuteDataDTO.getReviewsId());
        if (reviews != null) {
            if (reviews.getStatus().getValue() == EditStatus.FINISH.getValue()) {
                throw new MyException("该评审已经结束，不能再更新评审数据！");
            }

            // 修改测试用例编写状态
            List<Long> testCaseIds = new ArrayList<>();
            List<TestCase> testCaseList = iTestCaseService.listByIds(batchReviewsExecuteDataDTO.getTestCaseIds());
            for (TestCase testCase : testCaseList) {
                testCaseIds.add(testCase.getId());
                testCase.setEditStatus(batchReviewsExecuteDataDTO.getCaseStatus().getValue());
            }
            if (testCaseList.size() > 0) {
                iTestCaseService.updateBatchById(testCaseList);
            }

            // 删除旧的评审结果
            QueryWrapper<ReviewsResult> queryReviewsResultWrapper = new QueryWrapper<>();
            queryReviewsResultWrapper.eq("project_id", reviews.getProjectId());
            queryReviewsResultWrapper.eq("reviews_id", batchReviewsExecuteDataDTO.getReviewsId());
            queryReviewsResultWrapper.in("test_case_id", testCaseIds);
            reviewsResultDao.delete(queryReviewsResultWrapper);

            // 新增评审结果
            List<ReviewsResult> reviewsResultList = new ArrayList<>();
            for (Long testCaseId : testCaseIds) {
                ReviewsResult reviewsResult = new ReviewsResult();
                reviewsResult.setProjectId(reviews.getProjectId());
                reviewsResult.setReviewsId(batchReviewsExecuteDataDTO.getReviewsId());
                reviewsResult.setTestCaseId(testCaseId);
                reviewsResult.setStatus(batchReviewsExecuteDataDTO.getCaseStatus().getValue());
                reviewsResultList.add(reviewsResult);
            }
            iReviewsResultService.saveBatch(reviewsResultList);

            // 修改评审计划表中的 通过率 和 通过用例数
            QueryWrapper<ReviewsResult> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("project_id", reviews.getProjectId());
            queryWrapper.eq("reviews_id", batchReviewsExecuteDataDTO.getReviewsId());
            queryWrapper.eq("status", EditStatus.FINISH.getValue());
            reviews.setPassTestCases(reviewsResultDao.selectCount(queryWrapper).intValue());
            reviews.setPassRate(((Double) ((double) reviews.getPassTestCases() / (double) reviews.getTotalTestCase() * 100)).intValue());

            // 修改评审计划表中的 已评人数
            QueryWrapper<ReviewsRemark> queryReviewsRemarkWrapper = new QueryWrapper<>();
            queryReviewsRemarkWrapper.eq("project_id", reviews.getProjectId());
            queryReviewsRemarkWrapper.eq("reviews_id", batchReviewsExecuteDataDTO.getReviewsId());
            queryReviewsRemarkWrapper.select("DISTINCT reviewer_user_id");
            reviews.setReviewers(reviewsRemarkDao.selectCount(queryReviewsRemarkWrapper).intValue());

            reviewsDao.updateById(reviews);
        }

        return Response.success("批量更新测试用例编写状态成功！");
    }
}
